package simple.utils.concurrent;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Created with IntelliJ IDEA.
 * User: rehak
 * Date: 10/1/13
 * Time: 10:46 AM
 * To change this template use File | Settings | File Templates.
 */
public class SegmentedReadWriteLock {

    public enum Lock {
        READ, WRITE
    }

    private final ReentrantReadWriteLock[] locks;
    private final int concurrency;

    public SegmentedReadWriteLock(int concurrency) {
        this.concurrency = concurrency;
        this.locks = new ReentrantReadWriteLock[concurrency];
        for (int i = 0; i < concurrency; i++) {
            locks[i] = new ReentrantReadWriteLock();
        }
    }

    public int getConcurrency() {
        return concurrency;
    }

    public void lock(int index, Lock lock) {
        if (locks.length == 0) {
            return;
        }
        ReentrantReadWriteLock l = locks[index % concurrency];
        switch (lock) {
            case READ:
                l.readLock().lock();
                break;
            case WRITE:
                l.writeLock().lock();
                break;
            default:
                throw new IllegalArgumentException("Unknown lock type! " + lock);
        }
    }

    public void unlock(int index, Lock lock) {
        if (locks.length == 0) {
            return;
        }
        ReentrantReadWriteLock l = locks[index % concurrency];
        switch (lock) {
            case READ:
                l.readLock().unlock();
                break;
            case WRITE:
                l.writeLock().unlock();
                break;
            default:
                throw new IllegalArgumentException("Unknown lock type! " + lock);
        }
    }


}
